package com.lgvalle.material_animations;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.databinding.DataBindingUtil;
import android.os.Bundle;
import android.support.annotation.ColorRes;
import android.support.v4.content.ContextCompat;
import android.support.v7.widget.Toolbar;
import android.transition.Fade;
import android.transition.Transition;
import android.transition.TransitionInflater;
import android.transition.TransitionManager;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewAnimationUtils;
import android.view.ViewGroup;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.AnimationUtils;
import android.view.animation.Interpolator;
import android.widget.RelativeLayout;
import android.widget.TextView;
import com.lgvalle.material_animations.databinding.ActivityRevealBinding;
public class RevealActivity extends BaseDetailActivity implements View.OnTouchListener {
private static final int DELAY = 100;
private RelativeLayout bgViewGroup;
private Toolbar toolbar;
private Interpolator interpolator;
private TextView body;
private View btnRed;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
bindData();
setupWindowAnimations();
setupLayout();
setupToolbar();
}
private void bindData() {
ActivityRevealBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_reveal);
Sample sample = (Sample) getIntent().getExtras().getSerializable(EXTRA_SAMPLE);
binding.setReveal1Sample(sample);
}
private void setupWindowAnimations() {
interpolator = AnimationUtils.loadInterpolator(this, android.R.interpolator.linear_out_slow_in);
setupEnterAnimations();
setupExitAnimations();
}
private void setupEnterAnimations() {
Transition transition = TransitionInflater.from(this).inflateTransition(R.transition.changebounds_with_arcmotion);
getWindow().setSharedElementEnterTransition(transition);
transition.addListener(new Transition.TransitionListener() {
@Override
public void onTransitionStart(Transition transition) {
}
@Override
public void onTransitionEnd(Transition transition) {
// Removing listener here is very important because shared element transition is executed again backwards on exit. If we don't remove the listener this code will be triggered again.
transition.removeListener(this);
hideTarget();
animateRevealShow(toolbar);
animateButtonsIn();
}
@Override
public void onTransitionCancel(Transition transition) {
}
@Override
public void onTransitionPause(Transition transition) {
}
@Override
public void onTransitionResume(Transition transition) {
}
});
}
private void setupExitAnimations() {
Fade returnTransition = new Fade();
getWindow().setReturnTransition(returnTransition);
returnTransition.setDuration(getResources().getInteger(R.integer.anim_duration_medium));
returnTransition.setStartDelay(getResources().getInteger(R.integer.anim_duration_medium));
returnTransition.addListener(new Transition.TransitionListener() {
@Override
public void onTransitionStart(Transition transition) {
transition.removeListener(this);
animateButtonsOut();
animateRevealHide(bgViewGroup);
}
@Override
public void onTransitionEnd(Transition transition) {
}
@Override
public void onTransitionCancel(Transition transition) {
}
@Override
public void onTransitionPause(Transition transition) {
}
@Override
public void onTransitionResume(Transition transition) {
}
});
}
private void setupLayout() {
bgViewGroup = (RelativeLayout) findViewById(R.id.reveal_root);
toolbar = (Toolbar) findViewById(R.id.toolbar);
body = ((TextView) findViewById(R.id.sample_body));
View btnGreen = findViewById(R.id.square_green);
btnGreen.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
revealGreen();
}
});
btnRed = findViewById(R.id.square_red);
btnRed.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
revealRed();
}
});
View btnBlue = findViewById(R.id.square_blue);
btnBlue.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
revealBlue();
}
});
findViewById(R.id.square_yellow).setOnTouchListener(this);
}
private void revealBlue() {
animateButtonsOut();
Animator anim = animateRevealColorFromCoordinates(bgViewGroup, R.color.sample_blue, bgViewGroup.getWidth() / 2, 0);
anim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
animateButtonsIn();
}
});
body.setText(R.string.reveal_body4);
body.setTextColor(ContextCompat.getColor(this, R.color.theme_blue_background));
}
private void revealRed() {
final ViewGroup.LayoutParams originalParams = btnRed.getLayoutParams();
Transition transition = TransitionInflater.from(this).inflateTransition(R.transition.changebounds_with_arcmotion);
transition.addListener(new Transition.TransitionListener() {
@Override
public void onTransitionStart(Transition transition) {
}
@Override
public void onTransitionEnd(Transition transition) {
animateRevealColor(bgViewGroup, R.color.sample_red);
body.setText(R.string.reveal_body3);
body.setTextColor(ContextCompat.getColor(RevealActivity.this, R.color.theme_red_background));
btnRed.setLayoutParams(originalParams);
}
@Override
public void onTransitionCancel(Transition transition) {
}
@Override
public void onTransitionPause(Transition transition) {
}
@Override
public void onTransitionResume(Transition transition) {
}
});
TransitionManager.beginDelayedTransition(bgViewGroup, transition);
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
layoutParams.addRule(RelativeLayout.CENTER_IN_PARENT);
btnRed.setLayoutParams(layoutParams);
}
private void revealYellow(float x, float y) {
animateRevealColorFromCoordinates(bgViewGroup, R.color.sample_yellow, (int) x, (int) y);
body.setText(R.string.reveal_body1);
body.setTextColor(ContextCompat.getColor(this, R.color.theme_yellow_background));
}
private void revealGreen() {
animateRevealColor(bgViewGroup, R.color.sample_green);
body.setText(R.string.reveal_body2);
body.setTextColor(ContextCompat.getColor(this, R.color.theme_green_background));
}
private void hideTarget() {
findViewById(R.id.shared_target).setVisibility(View.GONE);
}
private void animateButtonsIn() {
for (int i = 0; i < bgViewGroup.getChildCount(); i++) {
View child = bgViewGroup.getChildAt(i);
child.animate()
.setStartDelay(100 + i * DELAY)
.setInterpolator(interpolator)
.alpha(1)
.scaleX(1)
.scaleY(1);
}
}
private void animateButtonsOut() {
for (int i = 0; i < bgViewGroup.getChildCount(); i++) {
View child = bgViewGroup.getChildAt(i);
child.animate()
.setStartDelay(i)
.setInterpolator(interpolator)
.alpha(0)
.scaleX(0f)
.scaleY(0f);
}
}
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
if (view.getId() == R.id.square_yellow) {
revealYellow(motionEvent.getRawX(), motionEvent.getRawY());
}
}
return false;
}
private void animateRevealShow(View viewRoot) {
int cx = (viewRoot.getLeft() + viewRoot.getRight()) / 2;
int cy = (viewRoot.getTop() + viewRoot.getBottom()) / 2;
int finalRadius = Math.max(viewRoot.getWidth(), viewRoot.getHeight());
Animator anim = ViewAnimationUtils.createCircularReveal(viewRoot, cx, cy, 0, finalRadius);
viewRoot.setVisibility(View.VISIBLE);
anim.setDuration(getResources().getInteger(R.integer.anim_duration_long));
anim.setInterpolator(new AccelerateInterpolator());
anim.start();
}
private void animateRevealColor(ViewGroup viewRoot, @ColorRes int color) {
int cx = (viewRoot.getLeft() + viewRoot.getRight()) / 2;
int cy = (viewRoot.getTop() + viewRoot.getBottom()) / 2;
animateRevealColorFromCoordinates(viewRoot, color, cx, cy);
}
private Animator animateRevealColorFromCoordinates(ViewGroup viewRoot, @ColorRes int color, int x, int y) {
float finalRadius = (float) Math.hypot(viewRoot.getWidth(), viewRoot.getHeight());
Animator anim = ViewAnimationUtils.createCircularReveal(viewRoot, x, y, 0, finalRadius);
viewRoot.setBackgroundColor(ContextCompat.getColor(this, color));
anim.setDuration(getResources().getInteger(R.integer.anim_duration_long));
anim.setInterpolator(new AccelerateDecelerateInterpolator());
anim.start();
return anim;
}
private void animateRevealHide(final View viewRoot) {
int cx = (viewRoot.getLeft() + viewRoot.getRight()) / 2;
int cy = (viewRoot.getTop() + viewRoot.getBottom()) / 2;
int initialRadius = viewRoot.getWidth();
Animator anim = ViewAnimationUtils.createCircularReveal(viewRoot, cx, cy, initialRadius, 0);
anim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
viewRoot.setVisibility(View.INVISIBLE);
}
});
anim.setDuration(getResources().getInteger(R.integer.anim_duration_medium));
anim.start();
}
}